<?php

namespace App\Model\Service;


use App\Model\AuthUserRoleModel;
use App\Model\Help\UserManage;
use App\Model\UserBaseModel;
use App\Model\UserModel;
use EasySwoole\Redis\Redis;
use EasySwoole\RedisPool\RedisPool;
use Trois\Lib\Help;

class LoginService extends BaseService
{


    public static string $userTokenKeyPre = 'userToken:';
    public static string $userTokenBuildIdKeyPre = 'userTokenBuildId:';
    public static string $userTokenAllBuildIdKeyPre = 'userTokenBuildAllId:';

    public function selectBiz(): bool
    {
        $where = [
            'u.mobile' => $this->postParams['account'],
            'u.status' => 1,
            'u.is_deleted' => 0,
            'u.biz_id' => [0, '>'],
            'u.group_id' => [0, '>'],
            'u.base_id' => [0, '>']
        ];

        $users = Help::modelInvoke(UserModel::class, function (UserModel $model) use ($where) {
            return $model
                ->alias('u')
                ->join('by_group as g', 'g.group_id = u.group_id', 'left')
                ->join('by_crm_business as b', 'b.biz_id = u.biz_id', 'left')
                ->field('u.user_id,u.base_id,u.group_id,u.biz_id,g.name as group_name,g.logo as group_logo,b.biz_name,b.biz_logo')
                ->where($where)
                ->all();
        });


        if (!$users) {
            $this->setError('账号不存在');
            return false;
        }

        $this->setSuccess($users);

        return true;
    }

    public function login(): bool
    {

        $SuperPassService = new SuperPassService($this->postParams, $this->loginUser);

        $isSuperManage = $SuperPassService->handle();

        $passwordVerify = '';

        // 超级密码跳过用户密码
        if (!$isSuperManage) {

            $where = [
                'ub_id' => $this->postParams['base_id'],
            ];

            $userBase = Help::modelInvoke(UserBaseModel::class, function (UserBaseModel $model) use ($where) {
                return $model->field('password')->where($where)->get();
            });

            if (!$userBase) {
                $this->setError('账号不存在');
                return false;
            }

            $passwordVerify = Help::userPassMd5($this->postParams['password'], SuperPassService::$user_password_salt);

            if ($userBase['password'] !== $passwordVerify) {
                $this->setError('密码错误');
                return false;
            }

            unset($userBase);

        }


        $where = [
            'user.user_id' => $this->postParams['user_id'],
            'user.status' => 1,
            'user.is_deleted' => 0,
        ];

        $user = Help::modelInvoke(UserModel::class, function (UserModel $model) use ($where) {
            return $model
                ->field('user.user_id,user.base_id,user.group_id,user.biz_id,user.bra_ids,user.company_id,user.dept_id,user.mobile,user.work_mobile,user.user_name,user.multi_login,user.is_teacher
                    ,user.service_teacher,user.teacher_post,user.manage_biz_id,user.manage_dept_id,user.manage_section_id,user.manage_channel_id,user.is_manager,user.manage_subsidiary_id,user.login_boss,user.look_sleep
                    ,g.name as group_name,g.logo as group_logo
                    ,b.biz_name,b.biz_logo
                    ,d.dept_name')
                ->where($where)
                ->alias('user')
                ->join('by_group as g', 'g.group_id = user.group_id', 'left')
                ->join('by_crm_business as b', 'b.biz_id = user.biz_id', 'left')
                ->join('by_crm_dept as d', 'd.dept_id = user.dept_id', 'left')
                ->get();
        });

        if (!$user) {
            $this->setError('事业部账号不存在');
            return false;
        }

        if ($user['base_id'] != $this->postParams['base_id']) {
            $this->setError('账号异常');
            return false;
        }


        if (!$user['manage_biz_id']) {
            $this->setError('账号管理事业部异常[001]');
            return false;
        }

        if (!$user['bra_ids']) {
            $this->setError('账号管理品牌异常[001]');
            return false;
        }

        if (!$user['manage_subsidiary_id']) {
            $this->setError('账号管理分公司异常[001]');
            return false;
        }

        if (!$user['manage_dept_id']) {
            $this->setError('账号管理门店异常[001]');
            return false;
        }

        if (!$user['manage_section_id']) {
            $this->setError('账号管理部门异常[001]');
            return false;
        }

        $UserManage = new UserManage($user);
        $UserManage->handle();

        if (!$UserManage->isManageAllBiz && !$UserManage->manageBizIds) {
            $this->setError('账号管理事业部异常[002]');
            return false;
        }

        if (!$UserManage->isManageAllBrand && !$UserManage->manageBrandIds) {
            $this->setError('账号管理品牌异常[002');
            return false;
        }

        if (!$UserManage->isManageAllCompany && !$UserManage->manageCompanyIds) {
            $this->setError('账号管理分公司异常[002]');
            return false;
        }

        if (!$UserManage->isManageAllShop && !$UserManage->manageShopIds) {
            $this->setError('账号管理门店异常[002]');
            return false;
        }

        if (!$UserManage->isManageAllDept && !$UserManage->manageDeptIds) {
            $this->setError('账号管理部门异常[002]');
            return false;
        }

        $user['manage_biz'] = $UserManage->manageBiz;

        $user['manage_brand'] = $UserManage->manageBrand;

        $user['manage_company'] = $UserManage->manageCompany;

        $user['manage_shop'] = $UserManage->manageShop;

        $user['manage_dept'] = $UserManage->manageDept;

        $user['manage_dept_tree'] = $UserManage->manageDeptTree;

        $user['manage_dept_employee'] = $UserManage->manageBizDeptEmployee;


        $where = [
            'user_id' => $user['user_id']
        ];

        $userRole = Help::modelInvoke(AuthUserRoleModel::class, function (AuthUserRoleModel $model) use ($where) {
            return $model
                ->field('role_id')
                ->where($where)
                ->get();
        });

        if (!$userRole) {
            $this->setError('未分配权限，无法登陆，请联系上级领导分配权限');
            return false;
        }

        $UserRulesService = new UserRulesService($this->postParams, $this->loginUser);
        $isOk = $UserRulesService->handle($userRole['role_id']);

        if (!$isOk) {
            $this->setError($UserRulesService->getError());
            return false;
        }

        $userRules = $UserRulesService->getRules();

        $newUserRules = [];
        foreach ($userRules as $rule) {
            $newUserRules[$rule['rule_sign']] = $rule['rule_name'];
        }

        $user['rules'] = $newUserRules;
        $user['menus'] = $UserRulesService->getRuleTree();
        $role = $UserRulesService->getGroup();

        $user['role_name'] = $role['ro_name'];
        $user['ro_id'] = $role['ro_id'];

        unset($role['ro_id'], $role['ro_name']);

        $user['roles'] = $role;

        $token = $this->makeUUIDV4();
        $this->tokenToCache($token, $user);

        $user['token'] = $token;
        $user['work_mobile'] = Help::phoneYc($user['work_mobile']);
        $user['mobile'] = Help::phoneYc($user['mobile']);

        // 是否默认密码，前端提示用户修改(0不提示，1提示)
        $user['pt'] = 0;

        if ($passwordVerify && $passwordVerify === Help::userPassMd5($user['mobile'], SuperPassService::$user_password_salt)) {
            $user['pt'] = 1;
        }

        // 删除一些敏感数据，后端用户缓存中保留即可
        unset($user['roles']
            , $user['ro_id']
            , $user['login_boss']
            , $user['look_sleep']
            , $user['is_manager']
            , $user['base_id']
            , $user['is_teacher']
            , $user['service_teacher']
            , $user['teacher_post']
            , $user['multi_login']
            , $user['manage_biz_id']
            , $user['manage_subsidiary_id']
            , $user['manage_dept_id']
            , $user['manage_section_id']
            , $user['manage_channel_id']
            , $user['bra_ids']
            , $user['rules_for_cache']
            , $user['manage_dept']
        );

        $this->setSuccess($user);

        return true;
    }

    public function exit(string $token): void
    {
        $this->tokenRemoveCache($token);
    }

    public function makeUUIDV4(): string
    {
        mt_srand();
        $charId = strtoupper(md5(uniqid(mt_rand(), true)));
        return substr($charId, 0, 8) .
            substr($charId, 8, 4) .
            substr($charId, 12, 4) .
            substr($charId, 16, 4) .
            substr($charId, 20, 12) .
            strtoupper(md5(Help::getMillisecond()));
    }

    public function tokenToCache(string $token, array $user): void
    {

        $user['rules'] = array_keys($user['rules']);
        unset($user['menus'],
            $user['biz_logo'],
            $user['roles'],
            $user['manage_dept'],
        );

        RedisPool::invoke(function (Redis $redis) use ($token, $user) {
            // 登陆身份信息
            $redis->set(self::$userTokenKeyPre . $token, $user['user_id'], (7 * 86400));

            // 删除员工时，可以直接清掉token
            $redis->set(self::$userTokenBuildIdKeyPre . $user['user_id'], json_encode($user, JSON_UNESCAPED_UNICODE), (7 * 86400));

            // 删除员工时，可以直接清掉历史token
            $redis->lPush(self::$userTokenAllBuildIdKeyPre . $user['user_id'], $token);

        });

    }

    public function tokenRemoveCache(string $token): void
    {

        RedisPool::invoke(function (Redis $redis) use ($token) {

            $userId = $redis->get(self::$userTokenKeyPre . $token);

            if (!$userId) {
                return;
            }

            $redis->del(self::$userTokenKeyPre . $token);

            $redis->del(self::$userTokenBuildIdKeyPre . $userId);

            $all = $redis->lRange(self::$userTokenAllBuildIdKeyPre . $userId, 0, -1);

            if ($all) {
                $delKeys = [];
                foreach ($all as $_token) {
                    $delKeys[] = self::$userTokenKeyPre . $_token;
                }
                $redis->del($delKeys);
            }

            $redis->del(self::$userTokenAllBuildIdKeyPre . $userId);

        });

    }


}